home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.02 Feb 90 / Mouse Source / TrackLocation.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-23  |  4.9 KB  |  202 lines  |  [TEXT/KAHL]

  1. /*                                        TrackLocation.c                                        */
  2. /*
  3.  * Copyright © 1989 Martin Minow. All rights reserved.
  4.  *
  5.  * These routines convert from display (mouse) coordinates
  6.  * to the internal DOT value that designates data.
  7.  *
  8.  * DOT
  9.  * TrackGetOffset(point, track_handle)
  10.  * Point                point;
  11.  * TrackHandle    track_handle;
  12.  *
  13.  *    TrackGetOffset returns the index of the character
  14.  *    corresponding to the given point (expressed in
  15.  *    window-local coordinates).
  16.  *
  17.  * _Track_mouse_to_dot()        Convert window-local mouse
  18.  *                coordinates to a character designator.
  19.  * _Track_word()                        Extend window-local coodinates
  20.  *                to designate the start and end of a word.
  21.  * _Track_is_white()                Determine if a character is
  22.  *                "whitespace".
  23.  * _Track_pixel_row()                Locate the row (line of text)
  24.  *                that is designated by the mouse vertical loc.
  25.  */
  26. #include "TrackEdit.h"
  27. #define TR        (*tr)
  28. #define NIL        0L
  29.  
  30. DOT
  31. TrackGetOffset(point, track_handle)
  32. Point                point;
  33. TrackHandle    track_handle;
  34. {
  35.         register TrackPtr    tr;
  36.         _Track_state            state;
  37.         DOT                                result;
  38.         
  39.         tr = _Track_lock(track_handle, &state);
  40.         result =_Track_mouse_to_dot(tr, point);
  41.         _Track_unlock(&state);
  42.         return (result);
  43. }
  44.  
  45. /*
  46.  * _Track_mouse_to_dot(mouse)
  47.  * Convert the mouse position (given in window-local
  48.  * coordinates) to an index to the specified character in
  49.  * the string.  If the mouse is in the left half of the
  50.  * character, the index refers to the selected character;
  51.  * otherwise it refers to the following character.
  52.  */
  53. DOT
  54. _Track_mouse_to_dot(tr, mouse)
  55. register TrackPtr    tr;
  56. Point                            mouse;
  57. {
  58.         register LONGINT    row;
  59.         register INTEGER    col;
  60.         register int            i;
  61.         register DOT            dot;
  62.         register DOT            next_row;
  63.         register int            width;
  64.         
  65.         row = _Track_pixel_row(tr, mouse.v);
  66.         if (row < 0)
  67.             return (0);
  68.         else if (row >= TR.nLines)
  69.             return (TR.textLength);
  70.         else {
  71.             dot = TR.lineStarts[row];
  72.             next_row = TR.lineStarts[row + 1];
  73.             col = mouse.h - _Track_h_origin(tr, row);
  74.             width = 0;
  75.             while (dot < next_row
  76.                     && (*TR.hText)[dot] != '\r') {
  77.                 width = CharWidth((*TR.hText)[dot]);
  78.                 if (col < width)
  79.                     break;
  80.                 col -= width;
  81.                 dot++;
  82.             }
  83.             /*
  84.              * If the mouse is in the right-half of the
  85.              * character, (and it's not at the end of the row),
  86.              * move it forward: note that the DOT value is
  87.              * between two characters.
  88.              */
  89.             if (dot < next_row && col >= (width / 2))
  90.                 dot++;
  91.         }
  92.         return (dot);
  93. }
  94.  
  95. /*
  96.  * _Track_word(tr, mouse, DOT *, DOT *)
  97.  * Extend dot in both directions to the nearest word
  98.  * boundary.  Note that the last character on the line is
  99.  * treated specially. Bug alert: FindWord uses a 16 bit
  100.  * integer for textLength and offset. Thus, as our indices
  101.  * are longs (so we can have a lot of text), we should
  102.  * really fiddle with *hText so FindWord only sees one
  103.  * line of text.
  104.  */
  105. void
  106. _Track_word(tr, mouse, word)
  107. register TrackPtr    tr;
  108. Point                            mouse;
  109. _Track_Loc                *word;
  110. {
  111.         register DOT            dot;
  112.         register LONGINT    row;
  113.         register DOT            end;
  114.         OffsetTable                offsets;
  115.         
  116.         dot = _Track_mouse_to_dot(tr, mouse);
  117.         if (_Track_is_set(tr, _Track_use_script_manager)) {
  118.             FindWord(
  119.                 *TR.hText,
  120.                 (INTEGER) TR.textLength,
  121.                 (INTEGER) dot,
  122.                 TRUE,
  123.                 NIL,
  124.                 offsets
  125.             );
  126. #if smgrVers >= 0x0210    /* See ScriptMgr.h                        */
  127.         /*
  128.          * In Think C version 4, the offset table is defined
  129.          * as a 3-element structure.
  130.          */
  131. #define START    offsets[0].offFirst
  132. #define END        offsets[0].offSecond
  133. #else
  134.         /*
  135.          * This is specific to Think C version 3, where the
  136.          * offset table is defined as a 6-element short vector.
  137.          * Warning: no longer tested.
  138.          */
  139. #define START    offsets[0]
  140. #define    END        offsets[1]
  141. #endif
  142.             word->start = (DOT) START;
  143.             word->end = (DOT) END;
  144.         }
  145.         else {        
  146.             row = _Track_row(tr, dot);
  147.             end = TR.lineStarts[row];
  148.             word->start = dot;
  149.             while (word->start > end
  150.                  && !_Track_is_white(
  151.                                  tr, *(TR.hText), word->start - 1)) {
  152.                 --(word->start);
  153.             }
  154.             word->end = dot;
  155.             if (_Track_pixel_row(tr, mouse.v) == row) {
  156.                 /*
  157.                  * Scan for the whitespace that follows this word.
  158.                  * Note that we don't scan if dot has crept into
  159.                  * the next line.
  160.                  */
  161.                 end = TR.lineStarts[row + 1];
  162.                 while (word->end < end
  163.                      && !_Track_is_white(tr, (*TR.hText), word->end))
  164.                     (word->end)++;
  165.             }
  166.         }
  167. }
  168.  
  169. /*
  170.  * _Track_is_white(track_pointer, text_pointer, index)
  171.  * Return TRUE if the character at this location is
  172.  * whitespace, calling the application's wordbreak
  173.  * routine if one is present.
  174.  */
  175. Boolean
  176. _Track_is_white(tr, ptr, index)
  177. register TrackPtr    tr;
  178. char                            *ptr;
  179. DOT                                index;
  180. {
  181.         if (TR.wordBreak == 0)
  182.             return (((unsigned) ptr[index]) <= ' ');
  183.         else {
  184.             return (CallPascalB(ptr, index, TR.wordBreak));
  185.         }
  186. }
  187.  
  188. /*
  189.  * Determine the row that contains this mouse location
  190.  * (in window-local coordinates).
  191.  */
  192. LONGINT
  193. _Track_pixel_row(tr, vpixel)
  194. register TrackPtr    tr;
  195. INTEGER                        vpixel;
  196. {
  197.         return (
  198.                 ((LONGINT) vpixel - TR.viewRect.top + TR.topPixel)
  199.             / TR.lineHeight
  200.         );
  201. }
  202.